package com.crane.common.framework.utils;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

/**
 * @author zhenxing.pi
 */
public class Jackson2JsonUtil {

    /***
     * 存储不存储class类型，转对象自行转换
     */
    private static ObjectMapper objectMapper = null;
    /**
     * 存储class类型
     */
    private static ObjectMapper classMapper = null;

    static {
        if (objectMapper == null) {
            objectMapper = new ObjectMapper();
            objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
            //不注释,会导致swagger报错
            //objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
            //关闭日期序列化为时间戳的功能
            objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
            //关闭序列化的时候没有为属性找到getter方法,报错
            objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
            //关闭反序列化的时候，没有找到属性的setter报错
            objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
            //序列化的时候序列对象的所有属性
            objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
            //反序列化的时候如果多了其他属性,不抛出异常
            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            //如果是空对象的时候,不抛异常
            objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            objectMapper.setDateFormat(dateFormat);
        }
        if (classMapper == null) {

        }
    }

    public static String toString(Object bean) {
        try {
            return objectMapper.writeValueAsString(bean);
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    public static <T> T toObject(String data, Class<T> clazz) {
        try {
            return (T) objectMapper.readValue(data.getBytes(), clazz);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static <T> T toObject(String data, TypeReference<T> valueTypeRef) {
        try {
            return (T) objectMapper.readValue(data, valueTypeRef);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    public static void main(String[] args) {
        List<Object> a = new ArrayList<>();
        a.add(null);
        a.add(null);
        System.out.println(Jackson2JsonUtil.toString(a));
    }

}
